/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.googlecode.ivybeans.module.completion;

import com.googlecode.ivybeans.facade.IvyLibrary;
import java.io.IOException;
import javax.swing.text.JTextComponent;
import org.apache.ivy.Ivy;
import org.apache.ivyde.common.completion.IvyCodeCompletionProcessor;
import org.apache.ivyde.common.model.IvyModelSettings;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectManager;
import org.netbeans.spi.editor.completion.CompletionProvider;
import org.netbeans.spi.editor.completion.CompletionTask;
import org.netbeans.spi.editor.completion.support.AsyncCompletionTask;
import org.openide.filesystems.FileObject;
import org.openide.loaders.DataObject;
import org.openide.util.Exceptions;
import org.openide.windows.TopComponent;

public abstract class IvyCompletionProvider implements CompletionProvider {

    public CompletionTask createTask(int queryType, JTextComponent component) {
        if (queryType == COMPLETION_QUERY_TYPE || queryType == COMPLETION_ALL_QUERY_TYPE) {
            final Ivy ivy = getIvyInstance();
            return new AsyncCompletionTask(
                    new CompletionQuery(
                        ivy,
                        getCodeCompletionProcessor(ivy, new IvyModelSettings() {

                public String getDefaultOrganization() {
                    return "";
                }

                public String getDefaultOrganizationURL() {
                    return "";
                }

                public Ivy getIvyInstance() {
                    return ivy;
                }

                public void logError(String message, Exception e) {
                    System.out.println(message);
                }
            }),
                    getProjectName()),
                    component);
        }
        return null;
    }
    
    protected abstract IvyCodeCompletionProcessor getCodeCompletionProcessor(Ivy ivy, IvyModelSettings settings);

    protected String getProjectName() {
        // TODO: is there a way to get the actual project name?
        return getProject().getProjectDirectory().getName();
    }

    
    public int getAutoQueryTypes(JTextComponent component, String typedText) {
        return COMPLETION_QUERY_TYPE;
    }

    private Ivy getIvyInstance() {
        Ivy ivy = null;
        Project project = getProject();
        if (project != null) {
            IvyLibrary ivyLibrary = project.getLookup().lookup(IvyLibrary.class);
            if (ivyLibrary != null) {
                ivy = ivyLibrary.getIvyInstance();
            }
        }
        if (ivy == null) {
            ivy = new Ivy();
            try {
                ivy.configureDefault();
            } catch (Exception ex) {
                Exceptions.printStackTrace(ex);
                ivy = null;
            }
        }
        return ivy;
    }

    protected Project getProject() {
        FileObject file = getPrimaryFile();
        if (file != null) {
            ProjectManager projectManager = ProjectManager.getDefault();

            while (file != null && (!file.isFolder() || !projectManager.isProject(file))) {
                file = file.getParent();
            }
            if (file != null) {
                try {
                    return projectManager.findProject(file);
                } catch (IOException ex) {
                    return null;
                } catch (IllegalArgumentException ex) {
                    return null;
                }
            }
        }
        return null;
    }

    protected FileObject getPrimaryFile() {
        TopComponent activatedTC = TopComponent .getRegistry().getActivated();
        if(activatedTC == null)
            return null;
        DataObject activeFile = activatedTC.getLookup().lookup(DataObject.class);
        if(activeFile == null)
            return null;

        return activeFile.getPrimaryFile();
    }
}
